/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pb138.videodes.entity;

import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import java.util.HashSet;
import java.util.Set;
 
/**
 * This class converts a DVD entity to XML, or XML to a DVD entity.
 *
 * @author pseudo
 */
public class DvdConverter implements Converter{

    @Override
    public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext mc) {
	Dvd dvd = (Dvd) o;
	writer.startNode("title");
	writer.setValue(dvd.getTitle());
	writer.endNode();
	
	writer.startNode("type");
	writer.setValue(dvd.getType().toString());
	writer.endNode();
	
	writer.startNode("content");
	    for(Movie m : dvd.getContent()){
		writer.startNode("movie");
		if (m.getId() != null){
		    writer.addAttribute("id", m.getId());    
		}    
		writer.endNode();
	    }
	writer.endNode();
    }

    @Override
    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext uc) {
	Dvd dvd = new Dvd();
	dvd.setId(reader.getAttribute("id"));
	Set<Movie> content = new HashSet<Movie>();
	dvd.setContent(content);
	
	while(reader.hasMoreChildren()){
	    reader.moveDown();	    
	    
	    if (reader.getNodeName().equalsIgnoreCase("title")){
		 dvd.setTitle(reader.getValue());	   
	    }
	    
	    if (reader.getNodeName().equalsIgnoreCase("type")){
		 dvd.setType(Enum.valueOf(DvdType.class, reader.getValue()));	   
	    }
	    
	    if (reader.getNodeName().equalsIgnoreCase("content")){
		while (reader.hasMoreChildren()){
		    reader.moveDown();	
		   
		    if (reader.getNodeName().equalsIgnoreCase("movie")){
			Movie movie = new Movie();
			movie.setId(reader.getAttribute("id"));
			content.add(movie);
			
			while (reader.hasMoreChildren()){
			    reader.moveDown();
			    
			    if (reader.getNodeName().equalsIgnoreCase("name")){
				movie.setName(reader.getValue());
			    }
			    
			    if (reader.getNodeName().equalsIgnoreCase("director")){
				movie.setDirector(reader.getValue());
			    }
			    
			    if (reader.getNodeName().equalsIgnoreCase("country")){
				movie.setCountry(reader.getValue());
			    }
			    
			    if (reader.getNodeName().equalsIgnoreCase("year")){
				movie.setYear(Integer.parseInt(reader.getValue()));
			    }
			    
			    if (reader.getNodeName().equalsIgnoreCase("genres")){
				Set<Genre> genres = new HashSet<Genre>();
				movie.setGenres(genres);
				
				while(reader.hasMoreChildren()){
				    reader.moveDown();
				     
				    if (reader.getNodeName().equalsIgnoreCase("genre")){
					genres.add(Enum.valueOf(Genre.class, reader.getValue()));
				    }
				    reader.moveUp();
				}
			    }
			    
			    if (reader.getNodeName().equalsIgnoreCase("actors")){
				Set<String> actors = new HashSet<String>();
				movie.setActors(actors);
				
				while(reader.hasMoreChildren()){
				    reader.moveDown();
				     
				    if (reader.getNodeName().equalsIgnoreCase("actor")){
					actors.add(reader.getValue());
				    }
				    reader.moveUp();
				}
			    }
			    reader.moveUp();
			}
		    }		    
		    reader.moveUp();
		}
	    }
	    reader.moveUp();
	}
	return dvd;
    }

    
    @Override
    public boolean canConvert(Class type) {
	return type.equals(Dvd.class);
    }
    
}
